#pragma once
#include <pthread.h>
#include <queue>
#include <iostream>
#include <unistd.h>
#define CAPACITY 10000
template <class T>
class MsgQueue {
public:
  MsgQueue() {
    capacity_ = CAPACITY;
    pthread_mutex_init(&lock_vec_, NULL);
    pthread_cond_init(&cond_cons_, NULL);
    pthread_cond_init(&cond_prod_, NULL);
  }
  
  ~MsgQueue() {
    pthread_mutex_destroy(&lock_vec_);
    pthread_cond_destroy(&cond_cons_);
    pthread_cond_destroy(&cond_prod_);
  }

  void push(const T& msg) {
   pthread_mutex_lock(&lock_vec_);
   while (vec_.size() >= capacity_) {

     pthread_cond_wait(&cond_prod_, &lock_vec_);
   }
   vec_.push(msg);
   pthread_mutex_unlock(&lock_vec_);
   pthread_cond_signal(&cond_cons_);
  }

  void pop(T* msg) {

   pthread_mutex_lock(&lock_vec_);
   while (vec_.empty()) {
     pthread_cond_wait(&cond_cons_, &lock_vec_);
   }
   *msg = vec_.front();
   vec_.pop();
   pthread_mutex_unlock(&lock_vec_);
   pthread_cond_signal(&cond_prod_);

  }

  //获取队列大小
  int GetSize() {
    return vec_.size();
  }
private:
  std::queue<T> vec_;
  size_t capacity_;

  pthread_mutex_t lock_vec_;
  pthread_cond_t cond_cons_;
  pthread_cond_t cond_prod_;
};
